package com.baizhi.config;


import com.baizhi.realm.MyRealm2;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;

/**
 * 创建一个shiro的配置类
 */
@Configuration
public class ShiroConfig {
    /**
     * 创建一个过滤器
     *
     * 在创建Bean的时候 如果要装配的对象在工厂中存在  可以直接在形参中声明  会被装配到
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//        1.设置过滤器链  在shiro实际上就是 设置过滤规则 登录页面不过滤
//        过滤链  书写过滤规则 哪些要拦截  哪些不拦截
        Map map = new HashMap();
//        设置过滤规则 需要自己改
//        anon  匿名可访问  不用登录就可以访问
//        authc 认证后可访问  登录后可以访问
        map.put("/login.jsp", "anon");
        map.put("/Admin/adminLogin.do","anon");


        map.put("/regeist.jsp", "anon");
        map.put("/Admin/adminRegeist.do","anon");

        map.put("/css/**","anon");
        map.put("/js/**","anon");
        map.put("/json/**","anon");
        map.put("/script/**","anon");
        map.put("/main/image/**","anon");
//        代表所有的都需要认证
        map.put("/**", "authc");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);

//        2.设置SecurityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        return shiroFilterFactoryBean;
    }

    /**
     * 2.创建securityManager
     */
    @Bean
    public DefaultWebSecurityManager getSecurityManager(MyRealm2 myRealm2){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//        设置自定义的realm
        securityManager.setRealm(myRealm2);
        return securityManager;
    }

    /**
     * 3.创建自定义的Realm
     */
    @Bean
    public MyRealm2 getRealmDemo(CredentialsMatcher credentialsMatcher){
        MyRealm2 myRealm2 = new MyRealm2();
//        加密处理 设置密码凭证器
        myRealm2.setCredentialsMatcher(credentialsMatcher);
        return myRealm2;
    }

    /**
     * 4.设置密码凭证器
     * @return
     */
    @Bean
    public CredentialsMatcher getCredentialsMatcher(){
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
//        设置算法的名字
        credentialsMatcher.setHashAlgorithmName("md5");
//        设置散列次数
        credentialsMatcher.setHashIterations(1024);
        return credentialsMatcher;
    }

    /**
     *  开启shiro aop注解支持.
     *  使用代理方式;所以需要开启代码支持;否则@RequiresRoles等注解无法生效
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}